package com.haoxuer.discover.activiti.data.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.haoxuer.discover.data.core.Updater;
import com.haoxuer.discover.activiti.data.dao.ActDao;
import com.haoxuer.discover.activiti.data.entity.Act;
import com.haoxuer.discover.activiti.data.service.ActService;

import com.haoxuer.discover.data.page.Filter;
import com.haoxuer.discover.data.page.Order;
import com.haoxuer.discover.data.page.Page;
import com.haoxuer.discover.data.page.Pageable;

import java.io.UnsupportedEncodingException;
import java.util.List;

import com.haoxuer.discover.data.utils.FilterUtils;
import org.springframework.context.annotation.Scope;


/**
* Created by imake on 2017年10月26日11:25:05.
*/


@Scope("prototype")
@Service
@Transactional
public class ActServiceImpl implements ActService {

	private ActDao dao;

	@Autowired
	private RepositoryService repositoryService;

	//	@Autowired
//	private ObjectMapper objectMapper;
	protected ObjectMapper objectMapper = new ObjectMapper();

	@Override
	@Transactional(readOnly = true)
	public Act findById(Long id) {
		return dao.findById(id);
	}


	@Override
    @Transactional
	public Act save(Act bean) {
		dao.save(bean);
		return bean;
	}

	@Override
	public Model create(String name, String key, String description, String category) {
		ObjectNode editorNode = objectMapper.createObjectNode();
		editorNode.put("id", "canvas");
		editorNode.put("resourceId", "canvas");
		ObjectNode properties = objectMapper.createObjectNode();
		properties.put("process_author", "jeesite");
		editorNode.put("properties", properties);
		ObjectNode stencilset = objectMapper.createObjectNode();
		stencilset.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
		editorNode.put("stencilset", stencilset);

		Model modelData = repositoryService.newModel();
		description = StringUtils.defaultString(description);
		modelData.setKey(StringUtils.defaultString(key));
		modelData.setName(name);
		modelData.setCategory(category);
		modelData.setVersion(Integer.parseInt(String.valueOf(repositoryService.createModelQuery().modelKey(modelData.getKey()).count()+1)));

		ObjectNode modelObjectNode = objectMapper.createObjectNode();
		modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, name);
		modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, modelData.getVersion());
		modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
		modelData.setMetaInfo(modelObjectNode.toString());

		repositoryService.saveModel(modelData);
		try {
			repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return modelData;

	}

	@Override
    @Transactional
	public Act update(Act bean) {
		Updater<Act> updater = new Updater<Act>(bean);
		return dao.updateByUpdater(updater);
	}

	@Override
    @Transactional
	public Act deleteById(Long id) {
		Act bean = dao.findById(id);
        dao.deleteById(id);
		return bean;
	}

	@Override
    @Transactional	
	public Act[] deleteByIds(Long[] ids) {
		Act[] beans = new Act[ids.length];
		for (int i = 0,len = ids.length; i < len; i++) {
			beans[i] = deleteById(ids[i]);
		}
		return beans;
	}


	@Autowired
	public void setDao(ActDao dao) {
		this.dao = dao;
	}

	@Override
    public Page<Act> page(Pageable pageable){
         return dao.page(pageable);
    }


    @Override
	public Page<Act> page(Pageable pageable, Object search) {
		List<Filter> filters=	FilterUtils.getFilters(search);
		if (filters!=null) {
			pageable.getFilters().addAll(filters);
		}
		return dao.page(pageable);
	}

    @Override
    public List<Act> list(int first, Integer size, List<Filter> filters, List<Order> orders) {
        return dao.list(first,size,filters,orders);}
}